<!--
 * @Description: description
 * @version: 0.1
 * @Author: youhuimin
 * @Date: 2021-08-17 17:50:03
 * @LastEditors: youhuimin
 * @LastEditTime: 2021-09-17 10:24:53
 * @FilePath: \xdeas-user-web\src\common\tree_point\index.vue
-->
<template>
  <div style="width:100%">
    <div v-if="showSearch" class="mb-16">
      <a-input-search
        style="width:100%;"
        placeholder="搜索监测点"
        v-model="searchValue"
        enter-button
        @search="onSearch"
      />
    </div>
    <div class="mb-8 fs-12" v-if="max != -1">
      <span class="c-909399">
        {{ maxTip }}
      </span>
      <span class="c-606266">{{ deviceValue.length || 0 }}/{{ max }}</span>
    </div>
    <leftTree
      :value="value"
      :list="treeData"
      :type="type"
      v-model="deviceValue"
      :unableValue="disableValue"
      :default-expand="defaultExpand"
      @change="handleChange"
      :max="max"
      ref="tree"
      class="pb-20"
      :replaceFields="replaceFields"
    ></leftTree>
    <template v-if="treeData.length == 0">
      <div class="flex-c pb-20">暂无数据</div>
    </template>
  </div>
</template>

<script>
let imgRoom = require("../../assets/images/deviceMonitor/local.png");
import leftTree from "./leftTree.vue";
import treeTools from "./treeTools.js";
export default {
  data() {
    return {
      imgRoom,
      treeData: [],
      userInfo: {},
      deviceValue: [], //选中的设备
      defaultExpand: [], //默认展开节点
      disableValue: [], //不可选中的节点
      deviceObj: [],
      searchValue: "",
      orignData: "",
      orignTreeList:[],//原始的树状结构
    };
  },
  components: {
    leftTree,
  },
  watch: {
    value(val) {
      if (val == this.deviceValue) return;
      this.deviceValue = val;
    },
    source: {
      handler: function(val) {
        this.init(val);
      },
      deep: true,
    },
  },
  props: {
    value: {},
    showSearch: {
      type: Boolean,
      default: false,
    },
    showAll: {
      type: Boolean,
      default: true,
    },
    //不可选中节点条件
    disableFuc: {
      type: Function,
      default: null,
    },
    //第一个选中的方法
    firstSelFuc: {
      type: Function,
      default: null,
    },
    type: {
      type: String,
      default: "radio", //checkbox 单选和多选
    },
    dataType: {
      type: String,
      default: "", //树的数据类型  带电表的  仅机房 的  room
    },
    max: {
      type: [String, Number],
      default: -1,
    },
    maxTip: {
      type: String,
      default: "已选择：",
    },
    source: {
      type: Array,
      default: () => {
        return [];
      },
    },
    replaceFields: {
      type: Object,
      default: () => {
        return {
          children: "leaf",
          title: "supervisePointName",
          key: "key",
          value: "id",
        };
      },
    },
    expandAll:{},
  },
  methods: {
    init(oriData) {
      //去除无关联机房
      let tree = oriData.filter((v) => {
        return !!v.id;
      });
      // 给节点加上parentId
      this.initTree(tree, "all");

      this.treeData = tree || [];
      // 设定第一个选中的node
      if (this.firstSelFuc) {
        this.setFirstNode(tree, this.firstSelFuc);
      }
      this.orignData = JSON.stringify(this.treeData);
      this.orignTreeList = treeTools.treeToList(tree,this.replaceFields.children);
      if(this.expandAll){
        this.defaultExpand = this.orignTreeList.map(v=>{
          return v.id
        })
      }
      this.deviceObj = this.orignTreeList.filter(v=>{return this.curValue.includes(v[this.replaceFields.value])})
    },
    initTree(arr, parentId) {
      arr.forEach((v, i) => {
        v.showImg =
          this.dataType == "room" || v.engineroomAndDeviceEnum == "ROOM";
        v.parentId = parentId;
        //  v.engineroomAndDeviceEnum == "ROOM" 不可选中的条件 例如:不能选择机房
        if (this.disableFuc && this.disableFuc(v)) {
          this.disableValue.push(v.id);
        }
        if (
          v[this.replaceFields.children] &&
          v[this.replaceFields.children].length > 0
        ) {
          this.initTree(
            v[this.replaceFields.children],
            v[this.replaceFields.value]
          );
        }
        // if (v.subRooms && v.subRooms.length > 0) {
        // v.subs = v.subRooms.concat(v.subs || []);
        // this.initTree(v[this.replaceFields.children], v[this.replaceFields.value]);
        // }
      });
    },
    handleChange(e) {
      console.log(e,'handleChange')
      if (this.type == "radio") {
        this.deviceObj = e.obj;
        this.$emit("update:value", e.value[0] || "");
        this.$emit("select", e.obj[0]);
      } else {
        let objArr = this.orignTreeList.filter(v=>{
          return e.value.includes(v[this.replaceFields.value])
        })
        this.deviceObj = e.obj;
        this.$emit("update:value", e.value || []);
        this.$emit("select", objArr);
        console.log('handleChange====objArr',objArr)
      }
    },
    setFirstNode(tree, fuc) {
      // fuc 默认选中节点 (node)=>{return node.engineroomAndDeviceEnum == "DEVICE"} subs :子节点参数
      let first = treeTools.treeFind(tree, fuc, this.replaceFields.children);

      // 默认设置第一个
      if (first) {
        let treePath = treeTools.treeFindPath(
          tree,
          (node) => {
            return node.id == first.id;
          },
          [],
          this.replaceFields.children
        );

        this.defaultExpand = treePath;
        this.deviceValue = [first[this.replaceFields.value]];
        this.deviceObj = [first];
        this.handleChange({
          value: this.deviceValue,
          obj: this.deviceObj,
        });
      }
    },
    // 搜索
    onSearch(e) {
      let treeData = JSON.parse(this.orignData);
      if (e) {
        this.treeData = this.deal(treeData, (v) => {
          return v[this.replaceFields.title].includes(e);
        });
        this.$refs.tree.toggleAll(true);
      } else {
        this.treeData = treeData;
        this.$refs.tree.toggleAll(false, "first");
      }
    },
    /**
     * 递归过滤节点，但保留原树结构，即符合条件节点的父路径上所有节点不管是否符合条件都保留
     * @param {Node[]} nodes 要过滤的节点
     * @param {node => boolean} predicate 过滤条件，符合条件的节点保留
     * @return 过滤后的根节点数组
     */
    deal(nodes, predicate) {
      // 如果已经没有节点了，结束递归
      if (!(nodes && nodes.length)) {
        return;
      }

      const newChildren = [];
      for (const node of nodes) {
        const subs = this.deal(node[this.replaceFields.children], predicate);

        // 以下两个条件任何一个成立，当前节点都应该加入到新子节点集中
        // 1. 子孙节点中存在符合条件的，即 subs 数组中有值
        // 2. 自己本身符合条件
        if ((subs && subs.length) || predicate(node)) {
          node[this.replaceFields.children] = subs;
          newChildren.push(node);
        }
      }
      return newChildren.length ? newChildren : void 0;
    },
  },
  mounted() {
    this.curValue = this.value;
    this.init(this.source);
  },
  created() {
    this.userInfo = JSON.parse(localStorage.getItem("userInfo"));
  },
};
</script>

<style scoped lang="less">
.roomList {
  width: 100%;
  max-width: 224px;
}
.room-menu-item {
  display: flex;
  justify-content: left;
  align-items: center;
  width: 100%;
  max-width: 224px;
  height: 36px;
  padding: 8px 16px;
  border-radius: 4px;
  border: 1px solid #e4e7ed;
  margin-bottom: 8px;
  cursor: pointer;
  -moz-user-select: none; /*火狐*/
  -webkit-user-select: none; /*webkit浏览器*/
  -ms-user-select: none; /*IE10*/
  -khtml-user-select: none; /*早期浏览器*/
  -webkit-touch-callout: none;
  user-select: none;
  &:hover,
  &.active {
    background: #ffffff;
    border: 1px solid #e4e7ed;
  }
}
.room-menu-item .img-room {
  width: 18px;
  height: 18px;
}
// .ant-menu {
//   background-color: inherit;
// }
// .ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected {
//   background-color: #ffffff;
//   color: #303133;
// }
// .ant-menu-item:hover {
//   color: #303133;
// }
// .ant-menu-vertical {
//   border-right: none;
// }
// .ant-menu-item {
//   height: 36px;
//   margin: 0;
//   font-size: 14px;
//   border: 1px solid #e4e7ed;
//   display: flex;
//   align-items: center;
//   border-radius: 4px;
//   padding-left: 16px;
// }
.roomList {
  width: 100%;
  max-width: 224px;
  .lineBoxDev:last-child {
    // background: red;
    .line {
      height: 26px;
    }
  }
}
.rightIcon {
  position: absolute;
  right: 0;
  color: #c0c4cc;
}
.lineBox,
.lineBoxDev {
  float: right;
  position: relative;
  right: 0;
  width: 85%;
  overflow: inherit;
  &::before {
    content: "";
    display: block;
    background: #e4e7ed;
    width: 16px;
    height: 1px;
    position: absolute;
    left: -16px;
  }
  .line {
    content: "";
    display: block;
    background: #e4e7ed;
    width: 1px;
    height: 26px;
    position: absolute;
    left: -16px;
    top: -10px;
  }
}
.lineBoxDev {
  width: 70%;
  .line {
    height: 44px;
  }
}
.lineBoxDev2 {
  .line {
    height: 26px;
  }
}
.minH100 {
  min-height: 100%;
}
.text-right {
  text-align: right;
}
.p20 {
  padding: 20px;
}
.h100 {
  height: 100%;
}
.pointer {
  cursor: pointer;
}
.router-container,
.ant-menu {
  background-color: inherit;
}
.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected {
  background-color: #ffffff;
  color: #303133;
}
.ant-menu-item:hover {
  color: #303133;
}
.ant-menu-vertical {
  border-right: none;
}
.ant-menu-item {
  height: 36px;
  margin: 0;
  font-size: 14px;
  border: 1px solid #e4e7ed;
  display: flex;
  align-items: center;
  border-radius: 4px;
  padding-left: 16px;
}
.devListItmeBox {
  // display: flex;
}
.devListItme {
  width: 278px;
  height: 124px;
  background: #ffffff;
  border-radius: 4px;
  margin-right: 16px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  border: 1px solid #f0f2f5;
  padding: 16px 24px;
}
.devListItme:nth-child(3n) {
  // margin-right: 0;
}
.alBoxT {
  width: 58px;
  height: 24px;
  background: #f65f54;
  border-radius: 4px;
}
</style>
